﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Linq;

namespace ClubWebsite
{
    public partial class Matches : System.Web.UI.UserControl
    {
        private Guid _teamID;
        public Guid TeamID
        {
            set
            {
                _teamID = value;
            }
        }

        private Guid _leagueID;
        public Guid LeagueID
        {
            set
            {
                _leagueID = value;
            }
        }

        private string _team1Label = "Team 1";
        public string Team1Label
        {
            get
            {
                return _team1Label;
            }
        }
        private string _team2Label = "Team 2";
        public string Team2Label
        {
            get
            {
                return _team2Label;
            }
        }

        private Guid _clubID;
        public Guid ClubID
        {
            set
            {
                _clubID = value;
            }
        }

        private bool _ignorePostbackCheck = false;
        public bool IgnorePostbackCheck
        {
            set
            {
                _ignorePostbackCheck = value;
            }
        }

        protected override void OnInit(EventArgs e)
        {
            Page.RegisterRequiresControlState(this);
            base.OnInit(e);
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if ((!IsPostBack) || (_ignorePostbackCheck))
            {
                using (MainDataClassesDataContext databaseDataContext = Functions.GetDatabaseDataContext())
                {
                    // Display a list of matches
                    DBMatch[] matches;
                    bool displayRounds = true;
                    if (_teamID != Guid.Empty)
                    {
                        matches = databaseDataContext
                            .DBMatches
                            .Where(m => (m.HomeTeamID == _teamID)
                                || ((m.VisitorTeamID != null) && (m.VisitorTeamID == _teamID)))
                            .OrderBy(m => m.UTC)
                            .ToArray();
                        displayRounds = false;
                    }
                    else if (_leagueID != Guid.Empty)
                    {
                        matches = databaseDataContext
                            .DBMatches
                            .Where(m => m.LeagueID == _leagueID)
                            .OrderBy(m => m.UTC)
                            .ToArray();
                    }
                    else
                    {
                        throw new ApplicationException("No team or league given.");
                    }
                    if (matches.Count() > 0)
                    {
                        StringBuilder list = new StringBuilder();
                        string previousRound = "";
                        foreach (DBMatch match in matches)
                        {
                            // Prepare the variables
                            string matchDate;
                            string homeTeam;
                            string homeTeamScore;
                            string visitorTeam;
                            string visitorTeamScore;
                            string location;
                            string round;
                            string comment = "";

                            // Determine if the match is a bye, postponed or canceled
                            bool bye = false;
                            bool byeCountsAsWin = false;
                            int byeScoreFor = 0;
                            bool displayHomeAwayLabel = true;
                            if (match.Bye.GetValueOrDefault() != 0)
                            {
                                bye = true;
                            }
                            if (match.LeagueID.GetValueOrDefault() != Guid.Empty)
                            {
                                var leagueProperties = databaseDataContext
                                    .Leagues
                                    .Where(l => l.ID == match.LeagueID)
                                    .Select(l => new { l.ByeCountsAsWin, l.ByeScoreFor, l.DisplayHomeVisitorLabels })
                                    .Single();
                                byeCountsAsWin = leagueProperties.ByeCountsAsWin != 0 ? true : false;
                                byeScoreFor = leagueProperties.ByeScoreFor;
                                displayHomeAwayLabel = leagueProperties.DisplayHomeVisitorLabels != 0 ? true : false;
                            }
                            bool postponed = false;
                            if ((match.Postponed.GetValueOrDefault() != 0))
                            {
                                postponed = true;
                                comment = "Postponed";
                            }
                            bool cancelled = false;
                            if ((match.Cancelled.GetValueOrDefault() != 0))
                            {
                                cancelled = true;
                                comment = "Cancelled";
                            }

                            // Match ID and type
                            matchDate = Functions.FormatDateText(match.UTC.ToLocalTime(), false);

                            // Team 1 / Team 2 label
                            if (displayHomeAwayLabel)
                            {
                                _team1Label = "Home Team";
                                _team2Label = "Visitor Team";
                            }

                            // Round
                            if (match.Round.GetValueOrDefault() != 0)
                            {
                                round = "Round " + match.Round.Value;
                            }
                            else
                            {
                                round = "";
                            }

                            // Home team
                            homeTeam = HttpUtility.HtmlEncode(match.HomeTeam.Description);

                            // Home score
                            if ((cancelled) || (postponed))
                            {
                                homeTeamScore = "N/A";
                            }
                            else if (bye)
                            {
                                if (byeCountsAsWin)
                                {
                                    homeTeamScore = byeScoreFor.ToString();
                                }
                                else
                                {
                                    homeTeamScore = "N/A";
                                }
                            }
                            else if (match.HomeScore.HasValue)
                            {
                                homeTeamScore = match.HomeScore.Value.ToString();
                            }
                            else
                            {
                                homeTeamScore = "";
                            }

                            // Visitor team
                            if (bye)
                            {
                                visitorTeam = "Bye (no match)";
                            }
                            else if (match.VisitorTeamID.GetValueOrDefault() != Guid.Empty)
                            {
                                visitorTeam = HttpUtility.HtmlEncode(match.VisitorTeam.Description);
                            }
                            else
                            {
                                visitorTeam = "";
                            }

                            // Visitor team score
                            if ((cancelled) || (postponed))
                            {
                                visitorTeamScore = "N/A";
                            }
                            else if (bye)
                            {
                                if (byeCountsAsWin)
                                {
                                    visitorTeamScore = "0";
                                }
                                else
                                {
                                    visitorTeamScore = "N/A";
                                }
                            }
                            else if (match.VisitorScore.HasValue)
                            {
                                visitorTeamScore = match.VisitorScore.Value.ToString();
                            }
                            else
                            {
                                visitorTeamScore = "";
                            }

                            // Location
                            if (cancelled)
                            {
                                location = "Cancelled";
                            }
                            else if (postponed)
                            {
                                if (match.PostponedMatchID.HasValue)
                                {
                                    location = "Postponed";
                                }
                                else
                                {
                                    // TODO: Allow the user to set the new match from a postponed match
                                    /*if (!match.IsLeagueMatchIDNull())
                                    {
                                        lineHTML.Append("Postponed (<a href=\"LeagueMatch.aspx?PostponedParent=" + match.LeagueMatchID + "\">click here</a> to set the new match)");
                                    }
                                    else if (!match.IsTournamentMatchIDNull())
                                    {
                                        lineHTML.Append("Postponed (<a href=\"TournamentMatch.aspx?PostponedParent=" + match.TournamentMatchID + "\">click here</a> to set the new match)");
                                    }
                                    else
                                    {*/
                                    location = "Postponed (new match not set yet)";
                                    /*}*/
                                }
                            }
                            else if (bye)
                            {
                                location = "Bye (no match)";
                            }
                            else if (match.LocationID.HasValue)
                            {
                                location = HttpUtility.HtmlEncode(match.Location.Description);
                            }
                            else
                            {
                                location = "";
                            }

                            // Create the row
                            StringBuilder row = new StringBuilder();

                            // Display the round if the round has changed
                            if ((displayRounds) && (round.Length > 0))
                            {
                                if (round != previousRound)
                                {
                                    previousRound = round;
                                    row.Append("  <tr><td colspan=\"10\"><strong>" + round + "</strong></td></tr>\r\n");
                                }
                            }

                            row.Append("  <tr>\r\n");
                            if (_teamID != Guid.Empty)
                            {
                                // Matches should be specific to a team
                                string opposition;
                                if (match.HomeTeamID == _teamID)
                                {
                                    opposition = visitorTeam;
                                }
                                else
                                {
                                    opposition = homeTeam;
                                }
                                string firstScore = "";
                                string secondScore = "";
                                string matchVerb;
                                if (((cancelled) || (postponed) || ((bye) && (!byeCountsAsWin))) && (match.UTC < DateTime.UtcNow))
                                {
                                    matchVerb = "N/A";
                                }
                                else if ((bye) && (byeCountsAsWin) && (match.UTC < DateTime.UtcNow))
                                {
                                    matchVerb = "Won";
                                }
                                else if ((match.HomeScore.HasValue) && (match.VisitorScore.HasValue))
                                {
                                    firstScore = Math.Max(match.HomeScore.Value, match.VisitorScore.Value).ToString();
                                    secondScore = Math.Min(match.HomeScore.Value, match.VisitorScore.Value).ToString();
                                    if (match.HomeScore.Value == match.VisitorScore.Value)
                                    {
                                        matchVerb = "Draw";
                                    }
                                    else if (((match.HomeScore.Value > match.VisitorScore.Value) && (match.HomeTeamID == _teamID))
                                        || ((match.HomeScore.Value < match.VisitorScore.Value) && (match.HomeTeamID != _teamID)))
                                    {
                                        matchVerb = "Won";
                                    }
                                    else
                                    {
                                        matchVerb = "Lost";
                                    }
                                }
                                else
                                {
                                    matchVerb = "";
                                }
                                string homeAway;
                                if ((displayHomeAwayLabel) && (!bye))
                                {
                                    if (match.HomeTeamID == _teamID)
                                    {
                                        homeAway = "Home";
                                    }
                                    else
                                    {
                                        homeAway = "Away";
                                    }
                                }
                                else
                                {
                                    homeAway = "N/A";
                                }

                                row.Append("    <td>" + matchDate + "</td>\r\n");
                                row.Append("    <td>" + opposition + "</td>\r\n");
                                row.Append("    <td>" + matchVerb + "</td>\r\n");
                                row.Append("    <td>" + firstScore + "</td>\r\n");
                                row.Append("    <td>" + secondScore + "</td>\r\n");
                                row.Append("    <td>" + homeAway + "</td>\r\n");
                                row.Append("    <td>" + comment + "</td>\r\n");
                                //row.Append("    <td>" + location + "</td>\r\n");
                            }
                            else
                            {
                                // Matches are not for a specific team
                                row.Append("    <td>" + matchDate + "</td>\r\n");
                                row.Append("    <td>" + homeTeam + "</td>\r\n");
                                row.Append("    <td>" + homeTeamScore + "</td>\r\n");
                                row.Append("    <td>" + visitorTeam + "</td>\r\n");
                                row.Append("    <td>" + visitorTeamScore + "</td>\r\n");
                                row.Append("    <td>" + comment + "</td>\r\n");
                                //row.Append("    <td>" + location + "</td>\r\n");
                            }
                            row.Append("  </tr>\r\n");
                            list.AppendLine(row.ToString());
                        }
                        litList.Text = list.ToString();
                    }
                    else
                    {
                        litNoList.Visible = true;
                        MatchListNoTeamSpecifiedHeader.Visible = false;
                    }

                    // Show the correct teable header
                    if (_teamID != Guid.Empty)
                    {
                        MatchListNoTeamSpecifiedHeader.Visible = false;
                        MatchListTeamSpecifiedHeader.Visible = true;
                    }
                }
            }
        }

        [Serializable()]
        private struct Properties
        {
            public Guid TeamID;
            public Guid LeagueID;
            public Guid ClubID;
            public Properties(Guid teamID, Guid leagueID, Guid clubID)
            {
                TeamID = teamID;
                LeagueID = leagueID;
                ClubID = clubID;
            }
        }

        protected override object SaveControlState()
        {
            return new Properties(_teamID, _leagueID, _clubID);
        }

        protected override void LoadControlState(object state)
        {
            if (state is Properties)
            {
                _teamID = ((Properties)state).TeamID;
                _leagueID = ((Properties)state).LeagueID;
                _clubID = ((Properties)state).ClubID;
            }
        }
    }
}